package nest.bb.spike

import grails.converters.JSON;

import org.codehaus.groovy.grails.web.json.JSONArray;
import org.codehaus.groovy.grails.web.json.JSONObject;

class PersonController {

	static allowedMethods = [save: "POST", update: "PUT", delete: "POST"]

	def index = {
		List<String> phoneTypes = PhoneTypeEnum.values()*.toString()

		withFormat {
			html { [phoneTypes: phoneTypes] }
		}
	}
	
	def printPage = {
		String out = '''
				<form>
				<input type='button' value='Print this page' onClick='window.print()'>
				</form>
				''';
		render out + params.id
	}

	def list = {
		//params.max = Math.min(params.max ? params.int('max') : 10, 100)
		List<Person> personInstanceList = Person.list(params)
		int personInstanceTotal = Person.count()

		withFormat {
			/*
			html {
				[personInstanceList: personInstanceList, personInstanceTotal: personInstanceTotal]
			}
			*/
			json {
				render(contentType: "application/json", status: 200) {
					array {
						for(Person p in personInstanceList) {
							person(
									id: p.id,
									firstName: p.firstName,
									lastName: p.lastName,
									emergencyContactsSize: p.emergencyContacts.size()
									)

						}
					}
				}
			}
		}
	}

	def create = {
		def personInstance = new Person()
		personInstance.properties = params
		return [personInstance: personInstance]
	}

	def save = {
		def personInstance = new Person(params)
		if (personInstance.save(flush: true)) {
			flash.message = "${message(code: 'default.created.message', args: [message(code: 'person.label', default: 'Person'), personInstance.id])}"
			redirect(action: "show", id: personInstance.id)
		}
		else {
			render(view: "create", model: [personInstance: personInstance])
		}
	}

	def show = {
		def personInstance = Person.get(params.id)
		if (!personInstance) {
			withFormat {
				json { render(contentType: "application/json", status: 404) }
			}
			return
		}

		withFormat {
			json {
				render(contentType: "application/json", status: 200) {
					firstName = personInstance.firstName
					lastName = personInstance.lastName
					emergencyContacts = array {
						for (EmergencyContact ec in personInstance.emergencyContacts) {
							contact(
									firstName: ec.firstName,
									lastName: ec.lastName,
									mainContact : ec.mainContact,
									phones: array {
										for (Phone p in ec.phones) {
											phone(phone: p.phone, phoneType: p.phoneType.toString())
										}
									}
									)
						}
					}
				}
				return
			}
		}
	}

	def edit = {
		def personInstance = Person.get(params.id)
		if (!personInstance) {
			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'person.label', default: 'Person'), params.id])}"
			redirect(action: "list")
		}
		else {
			return [personInstance: personInstance]
		}
	}

	def update = { UpdatePersonCommand cmd ->
		if (!cmd.validate()) {
			withFormat {
				json { render(contentType: "application/json", status: 500) }
			}
			return
		}

		def personInstance = Person.get(cmd.id)
		if (!personInstance) {
			withFormat {
				json { render(contentType: "application/json", status: 404) }
			}
			return
		}

		personInstance.firstName = cmd.firstName
		personInstance.lastName = cmd.lastName

		personInstance.emergencyContacts*.delete()
		personInstance.emergencyContacts.clear()

		cmd.emergencyContacts.each {
			EmergencyContact ec = new EmergencyContact(
					firstName: it.firstName,
					lastName: it.lastName,
					mainContact: it.mainContact
					)
			for (JSONObject p in it.phones) {
				ec.addToPhones(
						phone: p.phone,
						phoneType: p.phoneType as PhoneTypeEnum
						)
			}

			personInstance.addToEmergencyContacts(ec)
		}

		personInstance.save()

		withFormat {
			json {
				render(contentType: "application/json", status: 200)
			}
		}
		return
	}

	def delete = {
		def personInstance = Person.get(params.id)
		if (personInstance) {
			try {
				personInstance.delete(flush: true)
				flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'person.label', default: 'Person'), params.id])}"
				redirect(action: "list")
			}
			catch (org.springframework.dao.DataIntegrityViolationException e) {
				flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'person.label', default: 'Person'), params.id])}"
				redirect(action: "show", id: params.id)
			}
		}
		else {
			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'person.label', default: 'Person'), params.id])}"
			redirect(action: "list")
		}
	}
}

class UpdatePersonCommand {
	Integer id
	String firstName
	String lastName

	JSONArray emergencyContacts

	static constraints = {
		id			(nullable: false, blank: false)
		firstName	(nullable: false, blank: false)
		lastName	(nullable: false, blank: false)
	}
}